package com.gobang.service.impl;

import com.gobang.service.GameAlgorithm;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

/**
 * 游戏算法实现类
 * 实现五子棋游戏的核心算法功能
 * 
 * @author System
 * @since 1.0.0
 */
@Service
public class GameAlgorithmImpl implements GameAlgorithm {

    private static final Logger log = LoggerFactory.getLogger(GameAlgorithmImpl.class);

    /**
     * 棋盘大小
     */
    private static final int BOARD_SIZE = 15;

    /**
     * 获胜需要的连子数量
     */
    private static final int WIN_COUNT = 5;

    /**
     * 四个方向：水平、垂直、主对角线、副对角线
     */
    private static final int[][] DIRECTIONS = {{0, 1}, {1, 0}, {1, 1}, {1, -1}};

    @Override
    public boolean checkWin(int[][] board, int row, int col, int color) {
        log.debug("检查胜负条件，位置: ({}, {}), 颜色: {}", row, col, color);
        
        // 检查四个方向
        for (int[] direction : DIRECTIONS) {
            int count = 1; // 包含当前落子
            
            // 向正方向计数
            count += countDirection(board, row, col, direction[0], direction[1], color);
            
            // 向反方向计数
            count += countDirection(board, row, col, -direction[0], -direction[1], color);
            
            if (count >= WIN_COUNT) {
                log.info("五子连珠达成! 位置: ({}, {}), 颜色: {}, 方向: [{}, {}], 连子数: {}", 
                    row, col, color, direction[0], direction[1], count);
                return true;
            }
        }
        
        return false;
    }

    @Override
    public boolean isValidMove(int[][] board, int row, int col) {
        // 检查坐标边界
        if (row < 0 || row >= BOARD_SIZE || col < 0 || col >= BOARD_SIZE) {
            log.debug("坐标越界: ({}, {})", row, col);
            return false;
        }
        
        // 检查位置是否为空
        if (board[row][col] != 0) {
            log.debug("位置已被占用: ({}, {}), 当前值: {}", row, col, board[row][col]);
            return false;
        }
        
        return true;
    }

    @Override
    public int[][] initializeBoard() {
        log.debug("初始化棋盘，大小: {}x{}", BOARD_SIZE, BOARD_SIZE);
        return new int[BOARD_SIZE][BOARD_SIZE];
    }

    @Override
    public int[][] copyBoard(int[][] board) {
        if (board == null) {
            log.warn("尝试复制空棋盘");
            return null;
        }
        
        int[][] copy = new int[BOARD_SIZE][BOARD_SIZE];
        for (int i = 0; i < BOARD_SIZE; i++) {
            System.arraycopy(board[i], 0, copy[i], 0, BOARD_SIZE);
        }
        
        log.debug("棋盘复制完成");
        return copy;
    }

    @Override
    public int countPieces(int[][] board) {
        if (board == null) {
            log.warn("尝试统计空棋盘棋子数量");
            return 0;
        }
        
        int count = 0;
        for (int i = 0; i < BOARD_SIZE; i++) {
            for (int j = 0; j < BOARD_SIZE; j++) {
                if (board[i][j] != 0) {
                    count++;
                }
            }
        }
        
        log.debug("棋盘棋子总数: {}", count);
        return count;
    }

    /**
     * 向指定方向计数连续棋子
     *
     * @param board 棋盘状态
     * @param row 起始行
     * @param col 起始列
     * @param deltaRow 行方向增量
     * @param deltaCol 列方向增量
     * @param color 棋子颜色
     * @return 连续棋子数量
     */
    private int countDirection(int[][] board, int row, int col, int deltaRow, int deltaCol, int color) {
        int count = 0;
        int r = row + deltaRow;
        int c = col + deltaCol;
        
        while (r >= 0 && r < BOARD_SIZE && c >= 0 && c < BOARD_SIZE && board[r][c] == color) {
            count++;
            r += deltaRow;
            c += deltaCol;
        }
        
        return count;
    }
} 